public class HashBuck2 <K,V>{
    static class Node<K,V>{
        public K key;
        public V value;
        public Node<K,V> next;

        public Node(K key, V value) {
            this.key = key;
            this.value = value;
        }
    }
    public Node<K,V>[] array = (Node<K,V>[])new Node[10];
    public int usedSize;
    public static final double  LOAD_FACTOR = 0.75;
    //给哈希表中插入数据（头插法）
    public void put(K key,V value){
        int hash = key.hashCode();//将引用类型的数据使用hashCode方法转换为哈希码
        int index = hash % array.length;//使用哈希码计算数据的下标
        Node<K,V> cur = array[index];//定义一个Node<K,V>类型的变量,遍历index位置的链表
        while(cur != null){
            if(cur.key.equals(key)){
                cur.value = value;
                return;
            }
            cur = cur.next;
        }
        Node<K,V> node = new Node<>(key,value);
        node.next = array[index];
        array[index] = node;
        usedSize++;
        if(calculateLoadFactor() >= LOAD_FACTOR){
            //扩容
            resize();
        }
    }
    //计算负载因子
    private double calculateLoadFactor(){
        return usedSize*1.0 /array.length;//乘以1.0的原因是，usedSize是整数类型的，计算出来之后是整数，这里我们需要小数。
    }
    //扩容
    private void resize(){
      Node<K,V>[] newArray = (Node<K,V>[])new Node[2*array.length];
        for (int i = 0; i < array.length; i++) {
            Node<K,V> cur = array[1];
            while(cur != null){
                Node<K,V> curNext = cur.next;//创建一个curNode类型的变量，用来记录cur遍历到的结点的下一个位置
                int hash = cur.key.hashCode();//重新计算每个元素的哈希码
                int index = hash % newArray.length;//计算出cur遍历到的结点的在新数组中的位置
                cur.next = newArray[index];//采用头插法，将新数组的index位置的结点链接在新节点的地址域
                newArray[index] = cur;//再将结点链接在新的数组的index位置。
                cur = curNext;//将cur遍历到的结点放到新的数组当中之后，cur回到原来的数组的链表当中，遍历下一个结点
            }
        }
        array = newArray;//重新计算哈希之后，将数据全部插入新的数组之后，再将newArray
    }
    //通过查找key,返回value
    public V get(K key){
        int hash = key.hashCode();//将引用类型的对象转化为哈希码
        int index = hash % array.length;//计算key在哈希表当中的位置
        Node<K,V> cur = array[index];//定义cur遍历index位置的链表
        while(cur != null){//将链表遍历完，不进入
            if(cur.key.equals(key)){//当cur遍历到的结点的值等于key
                return cur.value;//返回cur结点的value值
            }
            //若不相同，则继续向后遍历，直到将链表遍历完成
            cur = cur.next;
        }
        //将链表遍历完成还是没有找到，则返回-1
        return null;
    }
}
